<?php
namespace WDB\Wrapper;
use WDB;

/**
 * Table wrapper class. Provides information about its columns and allows to retrieve contained records.
 * May or may not be reflecting a database table - this allows programmers to add virtual tables which are implemented
 * another way than binding data to database and combine them with database tables all under WDB API.
 *
 * @author Richard Ejem <richard(at)ejem.cz>
 * @package WDB
 */
interface iTable extends \Iterator, \Countable, \ArrayAccess
{
    // <editor-fold defaultstate="collapsed" desc="Table identification">
    /**
     * Returns name of this table
     *
     * @return string
     */
    public function getName();

    /**
     * Returns human-readable title of this table.
     *
     * @return string
     */
    public function getTitle();
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="array to string key serialization">
    /**
     * Returns serialized form of a key to string.
     *
     * @param array $k
     * @return string
     */
    public function serializeKey(array $k);

    /**.
     * Returns unserialized form of a key from string.
     *
     * @param string $data key data
     * @param array $keys key field names
     * @return array
     */
    public function unserializeKey($data, array $keys);
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="data mining (methods retrieving iRecord s)">
    /**
     * get record object identified by a key (which is associative array: columnname=>value) or a single column key value
     *
     * @param array|mixed $key
     * @return iRecord
     */
    public function getRecordByKey($key);

    /**
     * Returns record matching passed key or throws NotFound if not found.
     *
     * @param string record key
     * @return iRecord
     * @throws WDB\Exception\NotFound
     */
    public function getRecordByStringPK($key);

    /**
     * Get table's primary key as an array of column names or list of columns that emulate a primary key.
     *
     * @return array
     */
    public function getPrimaryKey();

    /**
     * Get table's primary key as an array of arrays of column names.
     *
     * @return array[]
     */
    public function getUniqueKeys();

    /**
     * fetches query result into a record object.
     *
     * @param WDB\Query\SelectedRow $row
     * @return WDB\Wrapper\iRecord
     */
    public function fetchRecord(WDB\Query\SelectedRow $row);

    /**
     * creates a new iRecord object bound to this table
     * @param array $data
     * @param int $mode
     * @return iRecord
     */
    public function newRecord($data = array(), $mode = WDB\Query\Insert::UNIQUE);

    /**
     * Elevates collection of select result rows to collection of iRecords of this table.
     *
     * @param WDB\Query\SelectedRow[] select result rows
     * @return iRecord[]
     */
    public function elevateRecords($rows);
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Classname providers for columns, records and webui layer objects">
    /**
     *
     * @param string column identifier name
     * @return string|NULL column wrapper class name or use default class
     */
    public function getColumnWrapperClass($columnName);

    /**
     *
     * @param string column identifier name
     * @return string|NULL column webui class name or use default class
     */
    public function getColumnWebUIClass($columnName);

    /**
     * Returns class name for webui class of this table (or null when default shoud be used)
     *
     * @return string
     */
    public function getWebUIClass();

    /**
     * Returns class name for wrapper of records in this table (or null when default shoud be used)
     *
     * @return string
     */
    public function getRecordWrapperClass();

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="column information">
    /**
     * @return iColumn[]
     */
    public function getColumns();

    /**
     * Allows columns to have aliases to be accessed through.
     * i.e. column which is (part of a) foreign key is not represented
     * by a standard column object, but a foreign column object
     * and the original column name is aliased to the foreign key name.
     *
     * @param string alias
     * @return string canonical name
     */
    public function getColumnCName($alias);

    /**
     * Adds a column wrapper to this table.
     *
     * @param iColumn
     * @param string|null column identifier. if null, $column->name is used.
     */
    public function addColumn(iColumn $column, $name = NULL);
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="WebUI configuration providers">
    /**
     * Returns true if this table shoud be listed in schema webUI table list.
     *
     * @return bool
     */
    public function isListedInSchemaAdmin();

    /**
     * Returns true if this table is accessible by webUI
     *
     * @return bool
     */
    public function isWebUIAccessible();

    /**
     * Returns true if records in this table can display detail in WebUI.
     *
     * @return bool
     */
    public function isUIDetail();

    /**
     * Returns true if records in this table can be edited in WebUI.
     *
     * @return bool
     */
    public function isUIEdit();

    /**
     * Returns true if records in this table can be deleted in WebUI.
     *
     * @return bool
     */
    public function isUIDelete();
    // </editor-fold>

    /**
     * loads record validators for the table
     *
     * @param WDB\Event\Event
     */
    public function fetchValidators(WDB\Event\Event $event);
}